# coding: utf-8

# -------------------------------------------------------------------------------
# Name:         utils.py
# Description:
# Author:       XiangjunZhao
# EMAIL:        2419352654@qq.com
# Date:         2019/11/18 17:32
# -------------------------------------------------------------------------------
import json
import logging
import re

from apps.HttpAutoTestService.core.extractor import Extractor
from apps.HttpAutoTestService.core.parser import regex_replace_variables, regex_replace_functions
from apps.HttpAutoTestService.core.validator import Validator

logger = logging.getLogger(__name__)

# 绝对http url正则表达式
absolute_http_url_regexp = re.compile(r"^https?://", re.I)


def build_url(base_url, url):
    """
    构建URL
    在url前面加上主机名，除非它已经是一个绝对url
    Args:
        base_url:
        url:

    Returns:

    """
    if absolute_http_url_regexp.match(url):
        return url
    elif base_url:
        return "{}/{}".format(base_url.rstrip("/"), url.lstrip("/"))
    else:
        logger.error("base url 缺失!")


def ensure_mapping_format(variables):
    """
    确认variables是mapping格式
    Args:
        variables: 原始参数

    Returns: 确定格式为dict的参数variables

    """
    if isinstance(variables, list):
        variables_dict = {}
        for map_dict in variables:
            if isinstance(map_dict, dict):
                variables_dict.update(map_dict)
            else:
                logger.error("参数格式错误！")
        return variables_dict
    elif isinstance(variables, dict):
        return variables
    elif isinstance(variables, str):
        variables = eval(variables)
        if isinstance(variables, (dict, list)):
            return ensure_mapping_format(variables)
        else:
            logger.error("参数格式错误！")
    else:
        logger.error("参数格式错误！")


def regex_parse_args(content, variables_mapping):
    """
    使用正则解析参数
    Args:
        content:
        variables_mapping:

    Returns:

    """
    content = regex_replace_variables(content=content, variables_mapping=variables_mapping)
    content = regex_replace_functions(content=content)
    return content


def parse_output_result(name, result, expect_result, http_session_context):
    """
    提取用例/扩展方法输出结果
    Args:
        name:测试用例/扩展方法 名称
        result:测试用例/扩展方法 执行结果
        expect_result:期望结果
        http_session_context:

    Returns:

    """
    output_result = None
    try:
        if result and isinstance(expect_result, dict) and expect_result.get('output'):
            # 创建提取器
            extractor = Extractor()
            # 统一格式化扩展方法的输出变量output
            extractor.uniform_output(expect_result.get("output"))
            # 提取输出变量
            output_result = extractor.extract_output(resp_obj=result)
            # 将提取的输出变量值更新到http_session_context实例的update_output_variables变量中
            http_session_context.update_output_variables(variables_mapping=output_result)

        variables_mapping = {**http_session_context.session_variables_mapping,
                             **http_session_context.output_variables_mapping}
        logger.info(f'测试用例/扩展方法【{name}】执行后，全局参数内容：{variables_mapping}')
    except Exception as e:
        logger.error(f"提取输出变量值异常，异常原因：{repr(e)}")
    finally:
        return output_result


def parse_validate_result(result, expect_result, http_session_context):
    """
    获取校验结果
    Args:
        result:
        expect_result:
        http_session_context:

    Returns:

    """
    # 创建校验器
    validator = Validator()
    # 统一格式化测试用例的校验变量validate
    validator.uniform_validate(expect_result.get("validate"))
    variables_mapping = {**http_session_context.session_variables_mapping,
                         **http_session_context.output_variables_mapping}
    validate_variables_list = regex_parse_args(content=validator.validate_variables_list,
                                               variables_mapping=variables_mapping)
    validator.validate_variables_list = json.loads(validate_variables_list) if validate_variables_list else []
    validate_pass, failure_reason = validator.validate(resp_obj=result)
    return validate_pass, failure_reason


def parse_ext_method_validate_result(result, expect_result, http_session_context):
    """
    校验扩展方法执行结果
    Args:
        result:扩展方法执行结果
        expect_result:期望结果
        http_session_context:

    Returns:

    """
    validate_pass = 'PASS'
    failure_reason = []
    if isinstance(expect_result, dict) and expect_result.get('validate', None):
        validate_pass, failure_reason = parse_validate_result(result=result, expect_result=expect_result,
                                                              http_session_context=http_session_context)
    return validate_pass, failure_reason


def parse_http_testcase_validate_result(result, expect_result, http_session_context):
    """
    校验测试用例执行结果
    Args:
        result:测试执行结果
        expect_result:期望结果
        http_session_context:

    Returns:

    """

    if isinstance(expect_result, dict) and not expect_result.get("validate", None):
        expect_result["validate"] = {"check": "status_code", "comparator": "eq", "expect": 200}
    validate_pass, failure_reason = parse_validate_result(result=result, expect_result=expect_result,
                                                          http_session_context=http_session_context)
    return validate_pass, failure_reason
